import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;
public class GameJPanel extends JPanel implements KeyListener , Runnable {
    MyTank mytank = null;
    Image image1 = null;
    Image image2 = null;
    Image image3 = null;
    Vector<EnemyTank> enemyTankvector = new Vector<>();
    Vector<Bomb> bombs = new Vector<>();
    Ball ball = new Ball();
    GameJPanel(int x,int y){
        mytank=new MyTank(x,y);
        for(int i = 0 ; i < 3 ; i++) {
            enemyTankvector.add(new EnemyTank(i * 180 + 5, 300));
            EnemyTank enemyTank = enemyTankvector.get(i);
            new Thread(enemyTank).start();
        }
        String string  = System.getProperty("user.dir");
        string += "\\";
        image1 = Toolkit.getDefaultToolkit().getImage(string+"bomb1.gif");
        image2 = Toolkit.getDefaultToolkit().getImage(string+"bomb2.gif");
        image3 = Toolkit.getDefaultToolkit().getImage(string+"bomb3.gif");
    }
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.fillRect(0,0,700,500);
        hitTank();
        hitMytank();
        toRun();
        trace();
        if(ball.isLife() == true) {
            drawBall(ball.getX(),ball.getY(),g);
        }
        if(mytank.life == true) {
            drawTank(mytank.getX(),mytank.getY(),g,mytank.getDirection(),mytank.getType());
        }
        for(int i = 0 ; i < 3 ; i++) {
            if(enemyTankvector.get(i).isLife() == true) {
                drawTank(enemyTankvector.get(i).getX(),enemyTankvector.get(i).getY(),g,enemyTankvector.get(i).getDirection(),enemyTankvector.get(i).getType());
            }
        }
        for(int i = 0 ; i < mytank.bulletVector.size() ; i++) {
            Bullet bullet = mytank.bulletVector.get(i);
            check(bullet);
            if(bullet.isLife()) {
                g.setColor(Color.WHITE);
                g.fill3DRect(bullet.getX(),bullet.getY(),3,3,false);
            }else {
                mytank.bulletVector.remove(bullet);
            }
        }
        for(int i = 0 ; i < enemyTankvector.size() ; i++) {
            EnemyTank enemyTank = enemyTankvector.get(i);
            for(int j = 0 ; j < enemyTank.enemyBullets.size() ;j++) {
                Bullet bullet = enemyTank.enemyBullets.get(j);
                check(bullet);
                if(bullet.isLife()) {
                    g.setColor(Color.WHITE);
                    g.fill3DRect(bullet.getX(),bullet.getY(),3,3,false);
                }else {
                    enemyTank.enemyBullets.remove(bullet);
                }
            }
        }
        for(int i = 0 ; i < bombs.size() ; i++) {
            Bomb bomb = bombs.get(i);
            if(bomb.getLife() == 9) g.drawImage(image1,bomb.getX(),bomb.getY(),20,20,this);
            if(bomb.getLife() == 6) g.drawImage(image2,bomb.getX(),bomb.getY(),20,20,this);
            if(bomb.getLife() == 3) g.drawImage(image3,bomb.getX(),bomb.getY(),20,20,this);
            bomb.lifeDown();
            if(bomb.isLive() == false) bombs.remove(bomb);
        }

     }
     public void drawBall(int x,int y,Graphics g) {
        g.setColor(Color.CYAN);
        g.drawOval(x,y,10,10);
     }
    int f = 0;
    int num = 10000000;
    int idx = -1;
     public void trace() {
        if(enemyTankvector.isEmpty()) {
            ball.setSpeed(0);
            ball.setKeep(false);
            return;
        }
        if(ball.isKeep() && f == 0) {
//            System.out.println(f);
            f++;
            for(int i = 0 ; i < enemyTankvector.size() ; i++) {
                EnemyTank enemyTank = enemyTankvector.get(i);
                if(!enemyTank.isLife()) continue;
                int distance = Math.abs(ball.getX()-enemyTank.getX()) * Math.abs(ball.getX()-enemyTank.getX()) + Math.abs(ball.getY()-enemyTank.getY()) * Math.abs(ball.getY()-enemyTank.getY());
                if(distance < num) {
//                System.out.println(idx);
                    idx = i;
                    num = distance;
                }
            }
        }
        if(ball.isKeep()) {//动没动
//          System.out.println(idx);

            EnemyTank enemyTank = enemyTankvector.get(idx);
            if(!enemyTank.isLife()) {
                ball.setLife(false);
            }
            int dir=enemyTank.getDirection();
            int ball_x=ball.getX();
            int ball_y=ball.getY();
            int tank_x=enemyTank.getX();
            int tank_y=enemyTank.getY();
            if(Math.abs(ball_x-tank_x)+Math.abs(ball_y-tank_y)>20){
                int op=Math.abs(ball_x-tank_x);
                int ui=Math.abs(ball_y-tank_y);
                if(op>=20){
                    if(ball_x>tank_x){
                        ball.setX(ball_x-6);
                    }
                    else {
                        ball.setX(ball_x+6);
                    }
                }
                else{
                    if(ui >= 20) {
                        if(ball_y>tank_y){
                            ball.setY(ball_y-6);
                        }
                        else {
                            ball.setY(ball_y+6);
                        }
                    }else {
                        ball.setX(enemyTank.getX() - 15);
                        ball.setY(enemyTank.getY() - 15);
                    }
                }
            }

        }
     }
    public void drawTank(int x,int y,Graphics g,int direction,int type) {
        if(type == 0) {
            g.setColor(Color.yellow);
        }else if(type == 1) {
            g.setColor(Color.pink);
        }
        //0向下 1向上 2向左 3向右
        if(direction == 0)  {
            g.fill3DRect(x,y,15,15,false);
            g.fill3DRect(x,y,5,5,false);
            g.drawLine(x+5,y+10,x+5,y+30);
        }else if(direction == 1) {
            g.fill3DRect(x,y,15,15,false);
            g.fill3DRect(x,y,5,5,false);
            g.drawLine(x+5,y-20,x+5,y+10);
        }else if(direction == 2) {
            g.fill3DRect(x,y,15,15,false);
            g.fill3DRect(x,y,5,5,false);
            g.drawLine(x-20,y+10,x+5,y+10);
        }else if(direction == 3) {
            g.fill3DRect(x,y,15,15,false);
            g.fill3DRect(x,y,5,5,false);
            g.drawLine(x+5,y+10,x+30,y+10);
        }
    }
    public void check(Bullet bullet) {
        if(bullet.getX() < 0 || bullet.getX() > 700 || bullet.getY() < 0 || bullet.getY() > 500) {
            bullet.setLife(false);
        }
    }
    public void toRun() {
        if(ball.getX() >= mytank.getX() && ball.getX() <= mytank.getX() + 15 && ball.getY() >= mytank.getY() && ball.getY() <= mytank.getY() + 15) {
            ball.setKeep(true);
            ball.setSpeed(3);
        }
    }
    //0向下 1向上 2向左 3向右
    public void hitTank() {
        for(int i = 0 ; i < mytank.bulletVector.size() ; i++) {
            Bullet bullet = mytank.bulletVector.get(i);
            for(int j = 0 ; j < enemyTankvector.size() ; j ++) {
                EnemyTank enemyTank = enemyTankvector.get(j);
                int tx = enemyTank.getX();
                int ty = enemyTank.getY();
                int xx = bullet.getX();
                int yy = bullet.getY();
                if(bullet.getDirection() == 0) yy += bullet.getSpeed();
                if(bullet.getDirection() == 1) yy -= bullet.getSpeed();
                if(bullet.getDirection() == 2) xx -= bullet.getSpeed();
                if(bullet.getDirection() == 3) xx += bullet.getSpeed();
                if(xx >= tx && xx <= tx + 15 && yy >= ty && yy <= ty + 15) {
                    enemyTank.setLife(false);
                    Bomb bomb = new Bomb(tx,ty);
                    bombs.add(bomb);
                    mytank.bulletVector.remove(bullet);
                }
            }
        }
    }
    public void hitMytank() {
        for(int i = 0 ; i < enemyTankvector.size() ; i++) {
            EnemyTank enemyTank = enemyTankvector.get(i);
            for(int j = 0 ; j < enemyTank.enemyBullets.size() ; j++) {
                int tx = mytank.getX();
                int ty = mytank.getY();
                int xx = enemyTank.bullet.getX();
                int yy = enemyTank.bullet.getY();
                if(enemyTank.getDirection() == 0) yy += enemyTank.getSpeed();
                if(enemyTank.getDirection() == 1) yy -= enemyTank.getSpeed();
                if(enemyTank.getDirection() == 2) xx -= enemyTank.getSpeed();
                if(enemyTank.getDirection() == 3) xx += enemyTank.getSpeed();
                if(xx >= tx && xx <= tx + 15 && yy >= ty && yy <= ty + 15) {
                    mytank.setLife(false);
                    Bomb bomb = new Bomb(tx,ty);
                    bombs.add(bomb);
                    mytank.bulletVector.remove(enemyTank.bullet);
                }
            }
        }
    }
//    public void hitTank()
    @Override
    public void keyTyped(KeyEvent e) {

    }
    @Override
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_W) {
            if(mytank.getY() - mytank.getSpeed() - 20>= 0) mytank.up();
            mytank.setDirection(1);
        }if(e.getKeyCode() == KeyEvent.VK_S) {
            if(mytank.getY() + mytank.getSpeed() + 20<= 500) mytank.down();
            mytank.setDirection(0);
        }if(e.getKeyCode() == KeyEvent.VK_A) {
            if(mytank.getX() - mytank.getSpeed() - 20>= 0) mytank.left();
            mytank.setDirection(2);
        }if(e.getKeyCode() == KeyEvent.VK_D) {
            if(mytank.getX() + mytank.getSpeed() + 20<= 700) mytank.right();
            mytank.setDirection(3);
        }
        if(e.getKeyCode() == KeyEvent.VK_J) {
            if(mytank.bulletVector.size() <= 5) {
                mytank.attack();
            }
        }
        this.repaint();
    }
    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() {
        while(true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            this.repaint();
        }
    }
}
